package hxy.dragon.secure

import kotlin.test.*

/**
 * 完整的端到端加密解密测试
 * 验证使用真实的 SSH ED25519 密钥对进行加密和解密
 */
class FullEndToEndTest {
    
    // 真实的SSH ED25519公钥
    private val publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPSEOTVqftlcxz24oP8erbsq/XqF9cOSjJu9zH4BCJjC aohanhongzhi@qq.com"
    
    // 对应的SSH ED25519私钥
    private val privateKey = """-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACD0hDk1an7ZXMc9uKD/Hq27Kv16hfXDkoybvcx+AQiYwgAAAJi5zU0Tuc1N
EwAAAAtzc2gtZWQyNTUxOQAAACD0hDk1an7ZXMc9uKD/Hq27Kv16hfXDkoybvcx+AQiYwg
AAAED4NfJ/T2amYrgStidoIsphfaFc30lGax/C4RA6YC1be/SEOTVqftlcxz24oP8erbsq
/XqF9cOSjJu9zH4BCJjCAAAAE2FvaGFuaG9uZ3poaUBxcS5jb20BAg==
-----END OPENSSH PRIVATE KEY-----"""
    
    @Test
    fun testFullEncryptionAndDecryption() {
        val cryptoService = CryptoService()
        
        // 测试消息
        val originalMessage = "Hello, World! 这是一条测试消息。"
        
        // 加密消息
        val encryptedData = encryptMessage(originalMessage, publicKey, cryptoService)
        
        // 验证加密后的数据不等于原始消息
        assertNotEquals(originalMessage, encryptedData, "加密后的数据应该与原始消息不同")
        
        // 解密消息
        val decryptedMessage = decryptMessage(encryptedData, privateKey, cryptoService)
        
        // 验证解密后的消息与原始消息相同
        assertEquals(originalMessage, decryptedMessage, "解密后的消息应该与原始消息完全一致")
    }
    
    @Test
    fun testMultipleEncryptionsProduceDifferentCiphertexts() {
        val cryptoService = CryptoService()
        val message = "Test message"
        
        // 多次加密同一消息
        val encrypted1 = encryptMessage(message, publicKey, cryptoService)
        val encrypted2 = encryptMessage(message, publicKey, cryptoService)
        
        // 由于每次生成不同的临时密钥和IV，密文应该不同
        assertNotEquals(encrypted1, encrypted2, "同一消息的多次加密应该产生不同的密文")
        
        // 但都应该能正确解密
        val decrypted1 = decryptMessage(encrypted1, privateKey, cryptoService)
        val decrypted2 = decryptMessage(encrypted2, privateKey, cryptoService)
        
        assertEquals(message, decrypted1)
        assertEquals(message, decrypted2)
    }
    
    @Test
    fun testEncryptionWithEmptyMessage() {
        val cryptoService = CryptoService()
        val emptyMessage = ""
        
        val encrypted = encryptMessage(emptyMessage, publicKey, cryptoService)
        val decrypted = decryptMessage(encrypted, privateKey, cryptoService)
        
        assertEquals(emptyMessage, decrypted, "空消息应该能正确加密和解密")
    }
    
    @Test
    fun testEncryptionWithLongMessage() {
        val cryptoService = CryptoService()
        
        // 创建一个长消息
        val longMessage = "这是一条很长的消息。".repeat(100)
        
        val encrypted = encryptMessage(longMessage, publicKey, cryptoService)
        val decrypted = decryptMessage(encrypted, privateKey, cryptoService)
        
        assertEquals(longMessage, decrypted, "长消息应该能正确加密和解密")
    }
    
    @Test
    fun testEncryptionWithSpecialCharacters() {
        val cryptoService = CryptoService()
        
        // 包含各种特殊字符的消息
        val specialMessage = "Hello! @#$%^&*()_+-=[]{}|;':\",./<>?`~\n\t中文测试🎉"
        
        val encrypted = encryptMessage(specialMessage, publicKey, cryptoService)
        val decrypted = decryptMessage(encrypted, privateKey, cryptoService)
        
        assertEquals(specialMessage, decrypted, "包含特殊字符的消息应该能正确加密和解密")
    }
    
    @Test
    fun testInvalidEncryptedDataFormat() {
        val cryptoService = CryptoService()
        
        // 测试无效格式的加密数据（Base64解码失败或长度不足）
        try {
            decryptMessage("invalid_data", privateKey, cryptoService)
            fail("应该抛出异常")
        } catch (e: Exception) {
            // 预期会抛出异常（可能是 IllegalArgumentException 或其他异常）
            assertTrue(true)
        }
    }
    
    @Test
    fun testKeyConversionConsistency() {
        // 验证密钥转换的一致性
        val ed25519Key = ByteArray(32) { i -> i.toByte() }
        
        val x25519Key1 = convertEd25519ToX25519Key(ed25519Key)
        val x25519Key2 = convertEd25519ToX25519Key(ed25519Key)
        
        // 相同的输入应该产生相同的输出
        assertContentEquals(x25519Key1, x25519Key2, "密钥转换应该是确定性的")
    }
}

